<?php
use Think\Model;
define ( 'Z_REBATE_CLI', $argv[1] == 'cli' );

global $log_file, $log_file_name;
$log_dir = dirname(__FILE__ ) . '/logs';
@mkdir ( $log_dir, 0777, true );
$log_file_name = $log_dir . '/' . date ( 'Y-m-d' ) . '.log';
$log_file = fopen ( $log_file_name, 'a+' );
function begin_echo_progress() {
    if (Z_REBATE_CLI) {
        echo "\n", str_repeat ( ' ', 63 );
    }
}
function echo_progress($member, $all, $index, $gifts, $money) {
    if (Z_REBATE_CLI) {
        printf ( str_repeat ( chr ( 8 ), 63 ) . "[ %3d %% ] %7d - %-7d, Gift: %-8s, Money : %-10s", intval ( $index * 100 / $all ), $index, $all, number_format ( $gifts ), number_format ( $money, 2 ) );
    }

    global $log_file;
    fwrite ( $log_file, sprintf ( "%11d %20s %8s %10s\n", $member ['id'], $member ['username'], number_format ( $gifts ), number_format ( $money, 2 ) ) );
}
function echo_print($s) {
    if (Z_REBATE_CLI) {
        print_r ( $s );
    }
    global $log_file;
    fwrite ( $log_file, $s );
}
function main() {
    global $log_file_name;

    // 输出开始时间
    $begin_time = microtime ( true );
    echo_print ( "Begin Time      : ".date('Y-m-d H:i:s')."\n" );

    $addr = $_SERVER['HTTP_HOST'];
    echo_print ( "HTTP HOST      : ".$addr.date('Y-m-d H:i:s')."\n" );

    // 是否是本地请求
    $date = date('Y-m-d' );
    $time = date('Y-m-d H:i:s' );

    // 开启事务
    M()->startTrans();

    try{
        // 获取分红配置
        $rebate_quota = M('RebateQuota')->lock(true)->where(array("date"=>$date))->find();

        // 无分红配置
        if (empty($rebate_quota)) {
            echo_print ( "No RebateQuota      : ".date('Y-m-d H:i:s')."\n" );
            throw new Exception ( "无分红配置\n" );
        }

        // 此日已经分红
        if ($rebate_quota ['status'] == 'rebated') {
            echo_print ( "RebateQuota rebated    : ".date('Y-m-d H:i:s')."\n" );
            throw new Exception ( "此日已经分红.\n" );
        }

        // 用户分红权数据
        $member_info =  M("Member")
            ->field("SUM(new_gift - expired_new_gift) AS all_new_gift,SUM(old_gift - expired_old_gift) AS all_old_gift,count(0) AS count")
            ->where("disabled = 0 AND last_rebate_date<'$date' AND (new_gift > expired_new_gift OR old_gift > expired_old_gift)")
            ->find();

        // 检索所有当前赠送权(所有的会员)
        $all_new_gift = $member_info['all_new_gift'];
        $all_old_gift = $member_info['all_old_gift'];
        $count = $member_info['count'];

        if (empty($all_new_gift) && empty($all_old_gift)) {
            echo_print ( "all_gift is null   : ".date('Y-m-d H:i:s')."\n" );
            throw new Exception ( '分红权数量为零' );
        }

        $new_per_gift = $rebate_quota['new_per_gift'];
        $old_per_gift = $rebate_quota['old_per_gift'];

        // 每个分红权金额
        if (empty($new_per_gift) && empty($old_per_gift)) {
            echo_print("per_gift is null   : ".date('Y-m-d H:i:s')."\n");
            throw new Exception ( '分红权金额必须 > 0' );
        }

        // 状态为等待
        if ($rebate_quota ['status'] == 'waiting') {
            // 更新分红状态、数量，钱数
            M("RebateQuota")->where(array("date"=>$date))->setField(array (
                "status" => "rebating",
                'gift_count' => $all_new_gift + $all_old_gift
            ));
        }

        // 要分的旧权和新权
        $money_to_rebate = $all_new_gift * $new_per_gift + $all_old_gift * $old_per_gift;
        $rebated_gift = M("Member")->field("SUM(new_gift - expired_new_gift) AS all_new_gift,SUM(old_gift - expired_old_gift) AS all_old_gift")->where("disabled=0 AND last_rebate_date>='$date'")->find();

        $rebated = M('Rebate')->field("sum(amount) as rebated")->where(array("DATE(create_time)"=>$date))->find();

        // 获取配置
        $rebateConfig = getConfig('rebate');
        $newMoney = $rebateConfig['newMoney'];
        $newScore = $rebateConfig['newScore'];
        $oldMoney = $rebateConfig['oldMoney'];
        $oldScore = $rebateConfig['oldScore'];
        $gift_amount = $rebateConfig['revokeAmount'];

        echo_print ( sprintf ( "Log File        : %10s\n", $log_file_name ) );
        echo_print ( sprintf ( "Rebate Date     : %10s\n", $date ) );
        echo_print ( sprintf ( "Rebate Type     : %10s\n", $rebate_quota['type'] ) );
        echo_print ( sprintf ( "Rebate Money    : %10s\n", number_format ( $money_to_rebate, 3 ) ) );
        echo_print ( sprintf ( "Rebated Money   : %10s\n", number_format ( $rebated['rebated'], 3 ) ) );
        echo_print ( sprintf ( "Total new Gift      : %10s\n", number_format ( $all_new_gift ) ) );
        echo_print ( sprintf ( "Total old Gift      : %10s\n", number_format ( $all_old_gift ) ) );
        echo_print ( sprintf ( "Rebated all_new_gift    : %10s\n", number_format ( $rebated_gift['all_new_gift'] ) ) );
        echo_print ( sprintf ( "Rebated all_old_gift    : %10s\n", number_format ( $rebated_gift['all_old_gift'] ) ) );
        echo_print ( sprintf ( "Per new Gift        : %10s\n", number_format ( $new_per_gift, 3 ) ) );
        echo_print ( sprintf ( "Per old Gift        : %10s\n", number_format ( $old_per_gift, 3 ) ) );
        echo_print ( sprintf ( "Member Count    : %10s\n", number_format ( $count ) ) );
        echo_print ( sprintf ( "newMoney    : %10s\n", number_format ( $newMoney ) ) );
        echo_print ( sprintf ( "newScore    : %10s\n", number_format ( $newScore ) ) );
        echo_print ( sprintf ( "oldMoney    : %10s\n", number_format ( $oldMoney ) ) );
        echo_print ( sprintf ( "oldScore    : %10s\n", number_format ( $oldScore ) ) );
        echo_print ( sprintf ( "gift_amount    : %10s\n", number_format ( $gift_amount ) ) );

        begin_echo_progress ();

        // 插入分红记录
        $date_str = date('YmdH');
        $rebate_sql = "INSERT INTO Rebate (
                            sn,
                            member_id,
                            create_time,
                            amount,
                            gift_count
                        )
                        SELECT
                            CONCAT('$date_str',substring(RAND(), 3, 10)) AS sn,
                            id AS member_id,
                            '$time' as create_time,
                            ((new_gift - expired_new_gift) * '$new_per_gift' + (old_gift - expired_old_gift) * '$old_per_gift') AS amount,
                            (new_gift - expired_new_gift + old_gift - expired_old_gift) AS gift_count
                        FROM
                            Member
                        WHERE
                            disabled = 0
                        AND last_rebate_date < '$date'
                        AND (new_gift > expired_new_gift OR old_gift > expired_old_gift)";
        $Model = new Model();
        $up[] =  $Model->execute($rebate_sql);
        echo_print ( "insert Rebate Ok   : ".date('Y-m-d H:i:s')."\n" );

        // 金钱记录
        $cashflow_sql = "INSERT INTO CashFlow (
                            member_id,
                            create_time,
                            date,
                            item,
                            item_id,
                            amount,
                            balance,
                            stock,
                            recharge,
                            referral_bonus
                        )
                        SELECT
                            Member.id AS member_id,
                            '$time' AS create_time,
                            '$date' AS date, 
                            'rebate' AS item,
                            0 AS item_id,
                           ((new_gift - expired_new_gift) * '$new_per_gift' + (old_gift - expired_old_gift) * '$old_per_gift') as amount,
                            (Member.balance + ((new_gift - expired_new_gift) * '$newMoney' * '$new_per_gift' + (old_gift - expired_old_gift) * '$oldMoney' * '$old_per_gift')) AS balance,
                            (Member.stock + ((new_gift - expired_new_gift) * '$newScore' * '$new_per_gift' + (old_gift - expired_old_gift) * '$oldScore' * '$old_per_gift')) AS stock,
                            Member.recharge,
                            Member.referral_bonus
                        FROM
                            Member
                        WHERE
                            Member.disabled = 0
                        AND Member.last_rebate_date < '$date'
                        AND (Member.new_gift > Member.expired_new_gift OR Member.old_gift > Member.expired_old_gift)";
        $Model = new Model();
        $up[] =  $Model->execute($cashflow_sql);
        echo_print ( "insert CashFlow Ok   : ".date('Y-m-d H:i:s')."\n" );

        // 赠送权变更记录
        $gift_sql = "INSERT INTO givegift (
                            member_id,
                            gift,
                            date,
                            type
                        )
                        SELECT
                            Member.id AS member_id,
                            -FLOOR((rebate_temp_new + (new_gift - expired_new_gift) * '$new_per_gift') / '$gift_amount') AS gift,
                            '$time' AS date, 
                            '13' AS type
                        FROM
                            Member
                        WHERE
                            Member.disabled = 0
                        AND Member.last_rebate_date < '$date'
                        AND (Member.new_gift > Member.expired_new_gift OR Member.old_gift > Member.expired_old_gift)
                        AND FLOOR((rebate_temp_new + (new_gift - expired_new_gift) * '$new_per_gift') / '$gift_amount') > 0";
        $Model = new Model();
        $up[] =  $Model->execute($gift_sql);
        echo_print ( "insert givegift Ok   : ".date('Y-m-d H:i:s')."\n" );

        // 权，积分，余额等变更
        $update_sql = "UPDATE Member
                        SET 
                        new_rebate = (new_gift - expired_new_gift) * '$new_per_gift',
                        old_rebate = (old_gift - expired_old_gift) * '$old_per_gift'
                        WHERE Member.disabled = 0
                        AND Member.last_rebate_date < '$date'
                        AND (Member.new_gift > Member.expired_new_gift OR Member.old_gift > Member.expired_old_gift)";
        $Model = new Model();
        $up[] =  $Model->execute($update_sql);

        $update_sql = "UPDATE Member
                        SET 
                        balance = balance + (new_rebate * '$newMoney' + old_rebate * '$oldMoney'),
                        stock = stock + (new_rebate * '$newScore' + old_rebate * '$oldScore'),
                        total_rebate = total_rebate + (new_rebate + old_rebate),
                        expired_new_gift = expired_new_gift + FLOOR((rebate_temp_new + new_rebate) / '$gift_amount'),
                        expired_old_gift = expired_old_gift + FLOOR((remain_rebate + old_rebate) / '$gift_amount'),
                        rebate_temp_new = (rebate_temp_new + new_rebate) % '$gift_amount',
                        remain_rebate = (remain_rebate + old_rebate) % '$gift_amount',
                        last_rebate_date = '$date'
                        WHERE Member.disabled = 0
                        AND Member.last_rebate_date < '$date'
                        AND (Member.new_gift > Member.expired_new_gift OR Member.old_gift > Member.expired_old_gift)";
        $Model = new Model();
        $up[] =  $Model->execute($update_sql);
        echo_print ( "update Member Ok   : ".date('Y-m-d H:i:s')."\n" );

        // 更新分红计划状态
        M("RebateQuota")->where(array("date" => $date))->setField(array(
            "status" => "rebated",
            "gift_count" => $all_new_gift + $all_old_gift,
            "real_quota" => $money_to_rebate
        ));

        // 提交
        M()->commit();
        echo_print ( "Success: ".date('Y-m-d H:i:s')."\n" );
    }catch (\Exception $e){
        M()->rollback();
        echo_print ( "Error: ".date('Y-m-d H:i:s').$e."\n" );
        return;
    }
    echo_print ( "\n\n\nEnd Time         : " . date ( 'Y-m-d H:i:s' ) . "\n" );
    echo_print ( "Cost Time        : " . (microtime ( true ) - $begin_time) . "s\n" );
}

main ();